//**************************************************************
//					新人研修用ソースプログラム	
//**************************************************************
//ファイル名：practice8-2.c						
//**************************************************************

//===========================						
//インクルード
//===========================
#include<stdio.h>

//===========================						
//マクロ
//===========================
#define EMP 128			// 128人分
#define NAME 21			// 社員名20文字分

//===========================						
//構造体定義
//===========================
struct list{
	int id;				/* ID */
	char name[21];		/* 名前 */
	int sex;			/* 性別 */
	int age;			/* 年齢 */
};

//===========================
//プロトタイプ宣言
//===========================
void newline(void);
void initialization(struct list []);
void emp_register(struct list []);
void emp_delete(struct list []);
void show_select(struct list [], int);
void emp_show(struct list);

//*********************************************************************
//機能名称　：メイン関数
//
//関数名　　：int main(void)
//引数　　　：なし
//戻り値　　：常に0
//機能　　　：
//*********************************************************************	
int main(void) {
	
	// 変数・構造体初期化
	int select = 0;
	struct list employee[EMP];
	initialization(employee);

	// メニュー画面表示	
	printf("1～6の番号を選択してください。\n\n");
	while(1){
		select = 0;

		printf("1:社員登録\n");
		printf("2:社員削除\n");
		printf("3:全社員表示\n");
		printf("4:男性一覧表示\n");
		printf("5:女性一覧表示\n");
		printf("6:終了\n");
		
		scanf("%d", &select);
		newline();

		switch(select){
		 case 1:
			//社員情報登録関数へ
			emp_register(employee);
			break;
		 case 2:
			//社員情報削除関数へ
			emp_delete(employee);
			break;
		 case 3:
			//表示情報選択関数へ
			show_select(employee, select);
			break;
		 case 4:
			//表示情報選択関数へ
			show_select(employee, select);
			break;
		 case 5:
			//表示情報選択関数へ
			show_select(employee, select);
			break;
		 case 6:
		 	//終了
			break;
		 default:
			printf("1～6の数字を選択してください。\n");
			break;
		}
		if(select == 6){
			break;
		}
	}
	return 0;
}
//*********************************************************************
//機能名称　：改行文字削除関数
//
//関数名　　：void newline(void)
//引数　　　：なし
//戻り値　　：なし
//機能　　　：fgets関数によって格納される意図しない改行文字を削除する。
//*********************************************************************	
void newline(void){
	int c;
	while ((c = getchar()) != EOF){
		if (c == '\n'){
			return;
		}
	}
}

//*********************************************************************
//機能名称　：構造体初期化関数
//
//関数名　　：void initialization(struct list initialize[]))
//引数　　　：struct list initialize[]
//戻り値　　：なし
//機能　　　：社員情報保持用構造体を初期化する。
//*********************************************************************	
void initialization(struct list initialize[]){
	// 先頭から初期化。
	int name_ini;
	int i = 0;
	// 初期化処理
	for(i = 0; i < EMP; i++){
			/* id */
			initialize[i].id = 0;
			/* 名前 */;
			for(name_ini = 0; name_ini < NAME; name_ini++){
				initialize[i].name[name_ini] = '\0';
			}
			/* 性別 */;
			initialize[i].sex = 0;
			/* 年齢 */
			initialize[i].age = 0;
	}
}

//*********************************************************************
//機能名称　：社員登録関数
//
//関数名　　：void emp_register(struct list s_register[])
//引数　　　：struct list s_register[]
//戻り値　　：なし
//機能　　　：社員情報(ID、名前、性別、年齢)を登録する。
//*********************************************************************	
void emp_register(struct list s_register[]){
	
	int ans = 0;		// 作業継続確認用
	int i = 0;
	char* line_change;	// 改行文字列削除作業用

	while(1){
		ans = 0;
		// 先頭からメンバ.IDが0の構造体を探す。
		for(i = 0; i < EMP; i++){
			// 登録可能
			if(s_register[i].id == 0){
			// 登録処理	
				/* id */
				s_register[i].id = (i + 1);
			
				/* 名前 */;
				printf("ID番号%dの名前を入力してください。\n", s_register[i].id = (i + 1));
				fgets(s_register[i].name,sizeof(s_register[i].name),stdin);
				// 改行文字削除
				for(line_change = s_register[i].name; *line_change != '\n'; line_change++);
				*line_change = '\0';
			
				/* 性別 */;
				printf("ID番号%dの性別を入力してください。\n(1:男性 2:女性)\n", s_register[i].id = (i + 1));
				scanf("%d", &s_register[i].sex);
				newline();
			
				/* 年齢 */
				printf("ID番号%dの年齢を入力してください。\n", s_register[i].id = (i + 1));
				scanf("%d", &s_register[i].age);
				newline();
				break;
			}
		}
		// 登録不可能 最後まで検索したが空きがない場合
		if(i < (EMP -1)){
			/* 作業継続確認 */
			printf("登録を続けますか。\n(1:はい 2:いいえ)\n");
			scanf("%d", &ans);
			newline();
			if(ans == 2){
				break;
			}
			if(ans >= 3 || ans <= 0){
				printf("1か2を入力してください。\n");
				break;
			}
		}
		else{
			printf("社員情報を登録するスペースがありません。\n");
			break;
		}
	}
}

//*********************************************************************
//機能名称　：社員削除関数
//
//関数名　　：void emp_delete(struct list s_delete[])
//引数　　　：struct list s_delete[]
//戻り値　　：なし
//機能　　　：社員情報(ID、名前、性別、年齢)を削除する。
//*********************************************************************
void emp_delete(struct list s_delete[]){
	int ans = 0;		// 作業継続確認用
	int id_search = 0;	// ID検索用
	int name_delete;	// 名前初期化用
	int i = 0;
		
	while(1){
		ans = 0;
		id_search = 0;
		// 削除対象のIDを入力
		printf("削除する社員のIDを入力してください。(1～128)\n");
		scanf("%d", &id_search);
		newline();
		if(id_search > 128 || id_search < 1){
			printf("範囲内のIDを入力してください。(1～128)\n");
			continue;
		}
	
		// 削除対象のメンバ.IDを持つ構造体を探す。
		for(i = 0; i < EMP; i++){
			// ID検出
			if(s_delete[i].id == id_search){
			// 削除処理	
				/* id */
				s_delete[i].id = 0;
			
				/* 名前 */;
				for(name_delete = 0; name_delete < NAME; name_delete++){
					s_delete[i].name[name_delete] = '\0';
				}
			
				/* 性別 */;
				s_delete[i].sex = 0;
			
				/* 年齢 */
				s_delete[i].age = 0;
				break;
			}
		}
		
		// ID未検出 最後まで検索したが見つからない場合
		if(i < (EMP - 1)){
			/* 作業継続確認 */
			printf("削除を続けますか。\n(1:はい 2:いいえ)\n");
			scanf("%d", &ans);
			newline();
			if(ans == 2){
				break;
			}
			else if(ans >= 3 || ans <= 0){
				printf("1か2を入力してください。\n");
				break;
			}
		}
		else{
			printf("入力されたIDは登録されていません。\n");
			break;
		}
	}
}

//*********************************************************************
//機能名称　：表示情報選択関数
//
//関数名　　：void show_select(struct list s_show[], int show_type)
//引数　　　：struct list s_show[], int show_type
//戻り値　　：なし
//機能　　　：社員情報保持用構造体を初期化する。
//*********************************************************************
void show_select(struct list s_show[], int show_type){
	int i = 0;
	
	// 表示する情報を選別する
	for(i = 0; i < EMP; i++){
		//全社員表示の場合
		if(show_type == 3){
			if(s_show[i].id != 0){
				emp_show(s_show[i]);
			}
		}
		//男性社員表示の場合
		if(show_type == 4){
			if(s_show[i].sex == 1){
			emp_show(s_show[i]);
			}
		}
		//女性社員表示の場合
		if(show_type == 5){
			if(s_show[i].sex == 2){
			emp_show(s_show[i]);
			}
		}		
	}
}

//*********************************************************************
//機能名称　：社員情報表示関数
//
//関数名　　：void emp_show(struct list s_show)
//引数　　　：struct list s_show
//戻り値　　：なし
//機能　　　：社員情報を表示する。
//*********************************************************************	
void emp_show(struct list s_show){
	/* id */
	printf("I　D：%d\n", s_show.id);
	/* 名前 */;
	printf("名前：%s\n", s_show.name);
	/* 性別 */
	if(s_show.sex == 1){
		printf("性別：男性\n");
	}
	else if(s_show.sex == 2){
		printf("性別：女性\n");
	}
	/* 年齢 */
	printf("年齢：%d\n", s_show.age);
}
